﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Xml;
using SW.Lite.Infrastructure.Exception;

namespace SW.Lite.Infrastructure.Configuration
{
    /// <summary>
    ///     Class SectionHandler.
    /// </summary>
    public class SectionHandler : IConfigurationSectionHandler
    {
        /// <summary>
        ///     创建配置节处理程序。
        /// </summary>
        /// <param name="parent">父对象。</param>
        /// <param name="configContext">配置上下文对象。</param>
        /// <param name="section">节 XML 节点。</param>
        /// <returns>创建的节处理程序对象。</returns>
        /// <exception cref="CodeException">
        ///     0x000001
        ///     or
        ///     0x000002
        ///     or
        ///     0x000003
        ///     or
        ///     0x000011
        ///     or
        ///     0x000012
        /// </exception>
        public object Create(object parent, object configContext, XmlNode section)
        {
            var htCfg = new Hashtable();
            if (section.Attributes != null && section.Attributes["DebugMode"] != null)
                htCfg.Add("DebugMode", section.Attributes["DebugMode"].Value.ToUpper() == "TRUE");
            else
                htCfg.Add("DebugMode", false);

            foreach (XmlNode node in section.ChildNodes)
            {
                switch (node.Name)
                {
                    case "Connection": //数据库连接配置
                        {
                            if (node.Attributes == null)
                            {
                                throw new CodeException(0x000001);
                            }

                            if (node.Attributes["Type"] == null || node.Attributes["Address"] == null ||
                                node.Attributes["Database"] == null || node.Attributes["UserName"] == null ||
                                node.Attributes["Password"] == null)
                            {
                                throw new CodeException(0x000002);
                            }

                            ConnectionType connType;
                            if (!Enum.TryParse(node.Attributes["Type"].Value, out connType))
                            {
                                throw new CodeException(0x000003);
                            }

                            var connCfg = new Connection
                            {
                                Type = connType,
                                Address = node.Attributes["Address"].Value,
                                Database = node.Attributes["Database"].Value,
                                UserName = node.Attributes["UserName"].Value,
                                Password = node.Attributes["Password"].Value
                            };
                            htCfg.Add("Connection", connCfg);
                            break;
                        }
                    case "Template":
                        {
                            if (node.Attributes == null || node.Attributes["Folder"] == null)
                            {
                                throw new CodeException(0x000011);
                            }

                            var templateCfg = new Template { Folder = node.Attributes["Folder"].Value };

                            foreach (XmlNode childNode in node.ChildNodes)
                            {
                                switch (childNode.Name)
                                {
                                    case "Razor":
                                        {
                                            if (childNode.Attributes != null && childNode.Attributes["Folder"] != null &&
                                                childNode.Attributes["Extension"] != null)
                                            {
                                                templateCfg.RazorFolder = childNode.Attributes["Folder"].Value;
                                                templateCfg.RazorExtension = childNode.Attributes["Extension"].Value;
                                            }
                                            else
                                            {
                                                throw new CodeException(0x000012);
                                            }
                                            break;
                                        }
                                    case "NVelocity":
                                        {
                                            if (childNode.Attributes != null && childNode.Attributes["Folder"] != null &&
                                                childNode.Attributes["Extension"] != null)
                                            {
                                                templateCfg.NVelocityFolder = childNode.Attributes["Folder"].Value;
                                                templateCfg.NVelocityExtension = childNode.Attributes["Extension"].Value;
                                            }
                                            else
                                            {
                                                throw new CodeException(0x000013);
                                            }
                                            break;
                                        }
                                }

                                htCfg.Add("Template", templateCfg);
                                break;
                            }
                            break;
                        }
                    case "Components":
                        {
                            var componentList = new List<Component>();
                            foreach (XmlNode childNode in node.ChildNodes)
                            {
                                if (childNode.Attributes != null && childNode.Attributes["Name"] != null &&
                                    childNode.Attributes["Instance"] != null &&
                                    childNode.Attributes["Service"] != null)
                                {
                                    componentList.Add(new Component
                                    {
                                        Instance = childNode.Attributes["Instance"].Value,
                                        Service = childNode.Attributes["Service"].Value,
                                        Name = childNode.Attributes["Name"].Value
                                    });
                                }
                                else
                                {
                                    throw new CodeException(0x000021);
                                }
                            }
                            htCfg.Add("Components", componentList);
                            break;
                        }
                    case "Security":
                        {
                            if (node.Attributes == null || node.Attributes["Key"] == null || node.Attributes["IV"] == null)
                            {
                                throw new CodeException(0x000031);
                            }

                            var securityCfg = new Security
                            {
                                Key = node.Attributes["Key"].Value,
                                IV = node.Attributes["IV"].Value,
                            };

                            htCfg.Add("Security", securityCfg);
                            break;
                        }
                    case "":
                        {
                            if (node.Attributes == null || node.Attributes["FaceFolder"] == null)
                            {
                                throw new CodeException(0x000032);
                            }

                            var uploadCfg = new Upload
                            {
                                FaceFolder = node.Attributes["FaceFolder"].Value
                            };

                            htCfg.Add("Upload", uploadCfg);
                            break;
                        }
                }
            }

            return htCfg;
        }
    }
}